package com.liumin.demo.comlink.base;



import com.liumin.comlink.http.exception.ApiException;
import com.liumin.comlink.http.exception.ExceptionHandle;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.functions.Function;

/**
 * 描述：使用observable方式异常处理,网络异常和自定义异常
 * 时间：2024/11/4 10:30
 * 作者:  Liumin
 */
public class ErrorHandlerObservable {

    public static <T> ObservableTransformer<T, T> handleResult() {
        return upstream -> upstream
                .onErrorResumeNext(new ErrorResumeFunction<>())
                .flatMap(new ResponseFunction<>());
    }


    /**
     * 非服务器产生的异常，比如本地无无网络请求，Json数据解析错误等等。
     *
     * @param <T>
     */
    private static class ErrorResumeFunction<T> implements Function<Throwable, ObservableSource<? extends T>> {

        @Override
        public ObservableSource<? extends T> apply(Throwable throwable) throws Exception {
            return Observable.error(ExceptionHandle.handleException(throwable));
        }
    }

    /**
     * 服务其返回的数据解析
     * 正常服务器返回数据和服务器可能返回的exception
     *
     * @param <T>
     */
    private static class ResponseFunction<T> implements Function<T, ObservableSource<T>> {

        @Override
        public ObservableSource<T> apply(T tResponse) throws Exception {
            BaseResponse baseResponse = (BaseResponse) tResponse;
            int code = Integer.parseInt(baseResponse.getCode());
            String message = baseResponse.getMsg();
            if (code == 200) {
                return createData(tResponse);
            } else {
                return Observable.error(new ApiException(code, message));
            }
        }
    }

    /**
     * 生成Observable
     *
     * @param t baseresponse
     */
    public static <T> Observable<T> createData(final T t) {
        return Observable.create(new ObservableOnSubscribe<T>() {
            @Override
            public void subscribe(ObservableEmitter<T> emitter) throws Exception {
                try {
                    emitter.onNext(t);
                    emitter.onComplete();
                } catch (Exception e) {
                    e.printStackTrace();
                    emitter.onError(e);
                }
            }
        });
    }


}
